﻿using System;
using System.Linq;
using System.Web.Mvc;
using Dexter.Domain.Model;
using Dexter.Logger.Contracts;
using Dexter.Services;
using Dexter.Web.Mvc.Controllers.Backoffice.Extensions;
using Dexter.Web.Mvc.Extensions;
using Dexter.Web.Mvc.Filters;
using Dexter.Web.Mvc.ViewModel.Backoffice.Binders;
using Dexter.Web.Mvc.ViewModel.Backoffice.ViewsData.CategoryController;
using Dexter.Web.Utils;

namespace Dexter.Web.Mvc.Controllers.Backoffice {
	[Authorize ( Roles = "Poster" )]
	[DexterCallFilter ( false )]
	public class CategoryController : BackOfficeControllerBase {
		readonly ICategoryService categoryService;

		public CategoryController ( IConfigurationService configurationService , IWebUtils webUtils , ILogger logger , IUrlBuilder urlBuilder , IContactService contactService , ICategoryService categoryService ) : base ( configurationService , webUtils , logger , urlBuilder , contactService ) {
			this.categoryService = categoryService;
		}

		[AcceptVerbs ( HttpVerbs.Get )]
		public ActionResult Index ( ) {
			var data = base.GetViewData ( new CategoryIndexViewData ( base.WebUtils , base.Configuration , base.UrlBuilder ) );
			
			data.Categories = categoryService.GetCategoriesDtoStructure ( ).ToFlat ( x => x.Categories );

			return View ( data );
		}

		[AcceptVerbs ( HttpVerbs.Get )]
		public ActionResult Editor ( int? id ) {
			
			var data = base.GetViewData ( new CategoryEditorViewData ( base.WebUtils, base.Configuration, base.UrlBuilder ) );
			data.Category = id.HasValue
			                	? categoryService.GetCategoryByKeyWithChilds ( id.Value ).ToCategoryBinder ( )
			                	: CategoryBinder.EmptyInstance ( );
			data.Categories = id.HasValue
			                  	? categoryService.GetAllCategories ( ).Where ( x => x.Id != id.Value ).ToDtos()
			                  	: categoryService.GetAllCategories ( ).ToDtos();

			return View ( data );
		}

		[ValidateAntiForgeryToken]
		[AcceptVerbs ( HttpVerbs.Post )]
		public ActionResult Editor (int? id,  CategoryBinder category ) {
			if ( !ModelState.IsValid ) {
				var data = base.GetViewData ( new CategoryEditorViewData ( base.WebUtils, base.Configuration, base.UrlBuilder ) );
				data.Categories = id.HasValue
				                  	? categoryService.GetAllCategories ( ).Where ( x => x.Id != id.Value ).ToDtos()
				                  	: categoryService.GetAllCategories ( ).ToDtos();

				data.Category = category;

				return View ( data );
			}

			Category cat;
			Category parent = null;

			if ( category.ParentId.HasValue ) {
				parent = categoryService.GetCategoryByKeyWithChilds ( category.ParentId.Value );
			}

			if ( id.HasValue && id.Value > 0 ) {
				cat = categoryService.GetCategoryByKeyWithChilds ( id.Value );
				cat.Parent = parent;

				if (!string.IsNullOrEmpty ( category.FeedBurnerUrl ))
					cat.FeedBurnerUrl = new Uri ( category.FeedBurnerUrl );

				cat.Name = category.Name;
				cat.Description = category.Description;

				categoryService.Update ( cat );
			}
			else {
				cat = Category.CreateNewCategory ( category.Name , parent );

				if (!string.IsNullOrEmpty ( category.FeedBurnerUrl ))
					cat.FeedBurnerUrl = new Uri ( category.FeedBurnerUrl );

				cat.Name = category.Name;
				cat.Description = category.Description;

				categoryService.Save ( cat );
			}

			return this.ReturnFeedback ( MessageType.Positive , "CategorySaved" , base.UrlBuilder.BackOffice.CategoryList );
		}

		[AcceptVerbs ( HttpVerbs.Get )]
		public ActionResult ConfirmDelete ( int id ) {
			if (id < 1)
				return HttpNotFound ( );

			var cat = categoryService.GetCategoryByKeyWithChilds ( id );

			if(cat == null)
				return HttpNotFound ( );

			var data = base.GetViewData ( new CategoryDeleteViewData ( base.WebUtils, base.Configuration, base.UrlBuilder ) );
			data.Category = cat;
			data.Categories = categoryService.GetAllCategories ( ).Where ( x => x.Id != id );

			return View ( data );
		}

		[AcceptVerbs ( HttpVerbs.Post )]
		[ValidateAntiForgeryToken]
		public ActionResult Delete ( int id, int? newCategoryId ) {
			
			if(!newCategoryId.HasValue)
				newCategoryId = 0;

			var cat = categoryService.GetCategoryByKeyWithChilds ( id );
			var newCat = newCategoryId.Value > 0
			             	? categoryService.GetCategoryByKeyWithChilds ( newCategoryId.Value )
			             	: null;

			if(cat == null)
				return this.ReturnFeedback ( MessageType.Negative, "CategoryNotFound", base.UrlBuilder.BackOffice.CategoryList );

			categoryService.DeleteCategory ( cat, newCat );

			return this.ReturnFeedback ( MessageType.Positive, "PostDeleted", base.UrlBuilder.BackOffice.CategoryList );
		}
	}
}